﻿using System;
using System.Windows.Forms;
using Sockets;

namespace test
{
    public partial class frmMain : Form
    {
        #region Member variables
        private ClientSocket testSocket = new ClientSocket();
        private delegate void simpleDelegate();
        private delegate void stringDelegate(string data);
        #endregion

        public frmMain()
        {
            InitializeComponent();

            // Subscribe to the ClientSocket events
            testSocket.OnConnectFailed += new System.EventHandler(connectFail);
            testSocket.OnConnectSuccess += new System.EventHandler(connectSuccess);
            testSocket.OnDisconnect += new System.EventHandler(disconnect);
            testSocket.OnDataReceived += new ClientSocket.dataReceivedHandler(dataReceived);
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            // Center form
            this.Left = (Screen.PrimaryScreen.WorkingArea.Width - this.Width) / 2;
            this.Top = (Screen.PrimaryScreen.WorkingArea.Height - this.Height) / 2;

            this.AcceptButton = btnSend;
        }

        // Required to keep things thread safe
        #region Subscribers
        private void connectSuccess(object sender, EventArgs e)
        {
            this.Invoke(new simpleDelegate(clientConnectedCallback));
        }

        private void connectFail(object sender, EventArgs e)
        {
            this.Invoke(new simpleDelegate(clientConnectFailCallback));
        }

        private void disconnect(object sender, EventArgs e)
        {
            this.Invoke(new simpleDelegate(clientDisconnectCallback));
        }

        private void dataReceived(object sender, DataReceivedEventArgs e)
        {
            this.Invoke(new stringDelegate(dataReceivedCallback), e.Data);
        }
        #endregion // This is all required to keep things thread safe.

        private void clientConnectFailCallback()
        {
            UIConnected(false);

            MessageBox.Show("Failed to connect to server", "Connect Failed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        private void clientConnectedCallback()
        {
            UIConnected(true);
        }

        private void clientDisconnectCallback()
        {
            UIConnected(false);

            MessageBox.Show("The remote host closed the connection");
        }

        private void dataReceivedCallback(string data)
        {
            txtMessages.Text += "THEM: " + data + Environment.NewLine;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (btnConnect.Text == "Connect")
            {
                txtIP.Enabled = false;
                txtPort.Enabled = false;
                btnConnect.Text = "Connecting...";

                int port = -1;

                try
                {
                    port = Int32.Parse(txtPort.Text);

                    if (port < 0 || port > 65535)
                        throw new Exception();
                }
                catch (Exception)
                {
                    MessageBox.Show("Please enter a valid port", "Invalid Port", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    UIConnected(false);
                    txtPort.Focus();
                    return;
                }

                if (txtIP.Text == "")
                {
                    MessageBox.Show("Please enter a valid IP address", "Invalid IP", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    UIConnected(false);
                    txtIP.Focus();
                    return;
                }

                testSocket.RemoteIP = txtIP.Text;
                testSocket.RemotePort = port;
                testSocket.Connect();
            }
            else
            {
                testSocket.Disconnect();
                btnConnect.Text = "Connect";
                txtIP.Enabled = true;
                txtPort.Enabled = true;
                txtSend.Enabled = false;
                btnSend.Enabled = false;
            }
        }

        private void UIConnected(bool connected)
        {
            txtIP.Enabled = !connected;
            txtPort.Enabled = !connected;
            txtSend.Enabled = connected;
            btnSend.Enabled = connected;

            btnConnect.Text = connected ? "Disconnect" : "Connect";
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (txtSend.Text != "")
            {
                testSocket.Send(txtSend.Text);
                txtMessages.Text += "YOU: " + txtSend.Text + Environment.NewLine;
                txtSend.Text = "";
            }
        }
    }
}
